package com.example.producer.controller;


import com.example.producer.comm.RabbitConstant;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;


/**
 * @description
 * @author shiguorang
 * @date 2023/6/29 11:09:13
 * @version 1.0
 */
@RestController
@RequestMapping("rabbitmq")
public class RabbitController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 简单模式
     * @param msg
     */
    @GetMapping(value = "/simple")
    public void simple(@RequestParam("msg") String msg) {
        rabbitTemplate.convertAndSend(RabbitConstant.SIMPLE_QUEUE_NAME, msg);
    }

    /**
     * work模式
     * @param msg
     */
    @GetMapping(value = "/work")
    public void work(@RequestParam("msg") String msg) {
        rabbitTemplate.convertAndSend(RabbitConstant.WORK_QUEUE_NAME, msg);
    }

    /**
     * 发布订阅模式
     * @param msg
     */
    @GetMapping(value = "/pubsub")
    public void pubsub(@RequestParam("msg") String msg) {
        rabbitTemplate.convertAndSend(RabbitConstant.PUBLISH_SUBSCRIBE_EXCHANGE_NAME, null, msg);
    }

    /**
     * 路由模式
     * @param key
     * @param msg
     */
    @GetMapping(value = "/routing")
    public void routing(@RequestParam("key") Integer key, @RequestParam("msg") String msg) {
        String keyName;
        if (key == 1){
            keyName = RabbitConstant.ROUTING_FIRST_QUEUE_ROUTING_KEY_NAME;
        }else if (key == 2){
            keyName = RabbitConstant.ROUTING_SECOND_QUEUE_ROUTING_KEY_NAME;
        }else if (key == 3){
            keyName = RabbitConstant.ROUTING_THIRD_QUEUE_ROUTING_KEY_NAME;
        }else {
            return;
        }
        // 给第一个队列发送消息
        rabbitTemplate.convertAndSend(RabbitConstant.ROUTING_EXCHANGE_NAME, keyName, msg);
    }

    /**
     * 主题模式
     * @param msg
     */
    @GetMapping(value = "/topics")
    public void topics(@RequestParam("msg") String msg) {
        // 给第一个队列发送消息，此时队列能接受到消息，因为队列通配符为 #.first.#，而 routing_key 为 topics.first.routing.key，匹配成功
        rabbitTemplate.convertAndSend(RabbitConstant.TOPICS_EXCHANGE_NAME, RabbitConstant.TOPICS_FIRST_QUEUE_ROUTING_KEY, msg);
        // 给第二个队列发送消息，此时队列也能接受到消息，因为队列通配符为 *.second.#，而 routing_key 为 topics.second.routing.key，匹配成功
        rabbitTemplate.convertAndSend(RabbitConstant.TOPICS_EXCHANGE_NAME, RabbitConstant.TOPICS_SECOND_QUEUE_ROUTING_KEY, msg);
        // 给第三个队列发送消息，此时队列无法接受到消息，因为队列通配符为 *.third.*，而 routing_key 为 topics.third.routing.key，匹配失败
        rabbitTemplate.convertAndSend(RabbitConstant.TOPICS_EXCHANGE_NAME, RabbitConstant.TOPICS_THIRD_QUEUE_ROUTING_KEY, msg);
    }

    /**
     * header模式
     */
    @GetMapping(value = "/header")
    public void header() {
        // 这条消息应该能被两个队列都接收到，第一个队列 all 匹配成功，第二个队列 hello-value any匹配成功
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setHeader("matchAll", "YES");
        messageProperties.setHeader("hello", "world");
        Message message = new Message("header first hello".getBytes(StandardCharsets.UTF_8), messageProperties);
        rabbitTemplate.convertAndSend(RabbitConstant.HEADER_EXCHANGE_NAME, null, message);

        // 这条消息应该只被第二个队列接受，第一个队列 all 匹配失败，第二个队列 matchAll-NO any匹配成功
        MessageProperties messagePropertiesSecond = new MessageProperties();
        messagePropertiesSecond.setHeader("matchAll", "NO");
        Message messageSecond = new Message("header second hello".getBytes(StandardCharsets.UTF_8), messagePropertiesSecond);
        rabbitTemplate.convertAndSend(RabbitConstant.HEADER_EXCHANGE_NAME, null, messageSecond);
    }

    /**
     * rpc模式
     */
    @GetMapping(value = "/rpc")
    public void rpc(@RequestParam("msg") String msg) {
        Object responseMsg = rabbitTemplate.convertSendAndReceive(RabbitConstant.RPC_QUEUE_NAME, msg);
        System.out.println("rabbit rpc response message: " + responseMsg);
    }

}
